using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;

namespace MemGuardian
{
    /// <summary>
    /// MemGuardian应用程序的主入口点
    /// 负责管理应用程序的单实例运行、管理员权限处理和内存释放功能
    /// </summary>
    internal static class Program
    {
        #region Windows API 声明
        
        // AllocConsole声明已删除，因为未被使用

        #endregion

        #region 私有字段

        /// <summary>
        /// 用于确保应用程序单实例运行的互斥锁名称
        /// 使用全局互斥锁防止多个实例同时运行
        /// </summary>
        private static readonly string MutexName = "MemGuardian_SingleInstance_Mutex";

        #endregion

        #region 主入口点

        /// <summary>
        /// 应用程序的主入口点
        /// 处理单实例检查、管理员权限管理和命令行参数
        /// </summary>
        /// <param name="args">命令行参数
        /// --memory-release: 表示需要以管理员权限执行内存释放操作</param>
        [STAThread]
        static void Main(string[] args)
        {
            // 使用互斥锁确保应用程序只有一个实例在运行
            using (var mutex = new Mutex(true, MutexName, out bool createdNew))
            {
                if (!createdNew)
                {
                    // 如果互斥锁已存在，说明有另一个实例正在运行
                    if (args.Length > 0 && args[0] == "--memory-release")
                    {
                        // 如果有内存释放参数，说明是管理员权限重启，需要强制替换现有实例
                        ForceReplaceExistingInstance();
                    }
                    else
                    {
                        // 普通启动，尝试激活现有窗口而不是创建新实例
                        ActivateExistingInstance();
                        return;
                    }
                }

                try
                {
                    // 初始化Windows Forms应用程序配置
                    // 包括高DPI设置、默认字体等
                    ApplicationConfiguration.Initialize();
                    
                    // 创建主窗体
                    var form1 = new Form1();
                    
                    // 检查是否有内存释放参数
                    if (args.Length > 0 && args[0] == "--memory-release")
                    {
                        // 延迟执行内存释放，确保窗体完全加载后再执行
                        // 这样可以避免在窗体初始化过程中执行可能导致UI卡顿的操作
                        form1.Shown += async (sender, e) => {
                            await form1.PerformMemoryReleaseAsync();
                        };
                    }
                    
                    // 启动应用程序消息循环
                    Application.Run(form1);
                }
                finally
                {
                    // 确保互斥锁被释放，即使发生异常也要释放
                    mutex.ReleaseMutex();
                }
            }
        }

        #endregion

        #region 实例管理方法

        /// <summary>
        /// 激活已存在的MemGuardian实例
        /// 当检测到已有实例运行时，尝试将焦点转移到现有窗口而不是创建新实例
        /// </summary>
        private static void ActivateExistingInstance()
        {
            try
            {
                // 查找系统中所有名为"MemGuardian"的进程
                var processes = Process.GetProcessesByName("MemGuardian");
                foreach (var process in processes)
                {
                    // 排除当前进程，只处理其他实例
                    if (process.Id != Process.GetCurrentProcess().Id)
                    {
                        // 尝试将窗口从最小化状态恢复到正常状态
                        ShowWindow(process.MainWindowHandle, SW_RESTORE);
                        // 将窗口置于前台并获取焦点
                        SetForegroundWindow(process.MainWindowHandle);
                        break; // 找到第一个实例后退出循环
                    }
                }
            }
            catch
            {
                // 如果激活现有实例失败，静默处理错误
                // 这可能是由于权限不足或进程已退出等原因
            }
        }

        /// <summary>
        /// 强制替换现有实例（用于管理员权限重启）
        /// 当需要以管理员权限执行内存释放时，需要先关闭现有实例再启动新实例
        /// </summary>
        private static void ForceReplaceExistingInstance()
        {
            try
            {
                // 查找系统中所有名为"MemGuardian"的进程
                var processes = Process.GetProcessesByName("MemGuardian");
                foreach (var process in processes)
                {
                    // 排除当前进程，只处理其他实例
                    if (process.Id != Process.GetCurrentProcess().Id)
                    {
                        try
                        {
                            // 首先尝试优雅地关闭进程（发送WM_CLOSE消息）
                            process.CloseMainWindow();
                            
                            // 等待进程响应关闭请求，最多等待3秒
                            if (!process.WaitForExit(3000))
                            {
                                // 如果进程没有在3秒内关闭，强制终止进程
                                process.Kill();
                            }
                        }
                        catch
                        {
                            // 如果优雅关闭失败，直接强制终止进程
                            try
                            {
                                process.Kill();
                            }
                            catch
                            {
                                // 忽略终止失败的情况，继续处理其他进程
                            }
                        }
                        finally
                        {
                            // 确保进程对象被正确释放
                            process.Dispose();
                        }
                    }
                }
                
                // 等待一小段时间确保进程完全关闭和资源释放
                Thread.Sleep(500);
            }
            catch
            {
                // 如果强制替换失败，静默处理错误
                // 这不会影响新实例的启动
            }
        }

        #endregion

        #region Windows API 声明和常量

        /// <summary>
        /// 显示窗口的Windows API
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="nCmdShow">显示命令</param>
        /// <returns>操作是否成功</returns>
        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        /// <summary>
        /// 将窗口置于前台的Windows API
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <returns>操作是否成功</returns>
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// 窗口显示命令常量：恢复窗口到正常状态
        /// </summary>
        private const int SW_RESTORE = 9;

        #endregion
    }
}